package com.axialproject.health.exchange.demo;

import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gdata.client.health.H9Service;
import com.google.gdata.client.http.AuthSubUtil;
import com.google.gdata.data.Entry;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.util.XmlBlob;
import com.axialproject.health.exchange.EMF;
import com.axialproject.health.exchange.PatientManager;
import com.axialproject.health.exchange.entity.Patient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class SendServlet extends HttpServlet {

    private static final Logger log = Logger.getLogger(SendServlet.class.getName());

    public void doPost (HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {

        if (!"google".equals(req.getParameter("to"))) {
            resp.setContentType("text/plain");
            resp.getWriter().println("Sorry ... Only Google Health is supported right now.");
            return;
        }

        Patient patient = null; // this is the patient we plan to connect
        Patient gpatient = null; // this is the google account for the patient
        EntityManager em = EMF.get().createEntityManager();
        try {
            patient = PatientManager.getPatientByUsernameAppName(em, req.getParameter("username"), "ringful-demo");
            List <Patient> patients = PatientManager.getLinkedPatients(em, patient.getId());
            for (Patient p : patients) {
                if ("google".equals(p.getAppName()) && p.getToken() != null) {
                    boolean validToken = false;
                    try {
                        Map<String, String> tokenInfo = AuthSubUtil.getTokenInfo(p.getToken(), null);
                        if (tokenInfo != null) {
                            validToken = true;
                        }
                    } catch (Exception te) {
                        log.log(Level.SEVERE, te.getMessage(), te);
                    }

                    if (validToken) {
                        gpatient = p;
                    }
                }
            }

            if (gpatient == null) {
                log.info ("The google token is no longer valid");
                resp.setContentType("text/plain");
                resp.getWriter().println("The google health access token for the user is no longer valid. The user has to go through the registration process again.");
                return;
            }

        } catch (Exception e) {
            log.log(Level.SEVERE, e.getMessage(), e);
            resp.setContentType("text/plain");
            resp.getWriter().println("There is a problem. Check the error log");
            return;
        } finally {
            em.close ();
        }

        if (gpatient != null) {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
            String ccrTemplate = readFileAsString("/allergy_ccr.xml");
            String ccr = ccrTemplate.replaceAll("\\#\\{UUID\\}", UUID.randomUUID().toString())
                                    .replaceAll("\\#\\{patient\\}", gpatient.getEmail())
                                    .replaceAll("\\#\\{start_date\\}", formatter.format(new Date()))
                                    .replaceAll("\\#\\{stop_date\\}", formatter.format(new Date ()))
                                    .replaceAll("\\#\\{severity\\}", req.getParameter("severity"))
                                    .replaceAll("\\#\\{allergen\\}", req.getParameter("allergen"));
            log.info ("CCR content is " + ccr);
            Entry newNotice = new Entry();
            newNotice.setTitle(new PlainTextConstruct("Self Recorded Allergy Info"));
            newNotice.setContent(new PlainTextConstruct(req.getParameter("note")));
            if (ccr != null) {
                XmlBlob ccrElement = new XmlBlob();
                ccrElement.setBlob(ccr);
                newNotice.setXmlBlob(ccrElement);
            }
            try {
                H9Service service = new H9Service("Ringful-H9Sample-1.0");
                service.setAuthSubToken(gpatient.getToken());
                // Entry createdNotice = service.insert(new URL("https://www.google.com/health/feeds/register/default"), newNotice);
                Entry createdNotice = service.insert(new URL("https://www.google.com/h9/feeds/register/default"), newNotice);
            } catch (Exception e) {
                log.log(Level.SEVERE, e.getMessage(), e);
                resp.setContentType("text/plain");
                resp.getWriter().println("There is a problem sending the CCR to H9.");
                return;
            }

            // Already registered
            resp.setContentType("text/html");
            resp.getWriter().println("The CCR record is successfully sent to Google Health account for " + gpatient.getEmail());
        }

    }

    private String readFileAsString(String fileOnClasspath) throws IOException{
        InputStream is = this.getClass().getResourceAsStream(fileOnClasspath);
        StringBuilder fileData = new StringBuilder(1000);
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        char[] buf = new char[1024];
        int numRead=0;
        while((numRead=reader.read(buf)) != -1){
            fileData.append(buf, 0, numRead);
        }
        reader.close();
        return fileData.toString();
    }
}
